import 'package:love_app/enum/chat_type.dart';
import 'package:love_app/model/socket_model.dart' as SKModel;
import 'package:sqflite/sqflite.dart';

import './abstract_base.dart';

class SocketDb extends BaseDb {
  final String dbTableName = "SocketDb"; // 数据库表名
  /// 以下是数据库字段
  final String columnId = "id"; // 表id
  final String columnLogId = "logId"; // 服务器数据对应的id
  final String columnSendUid = "sendUid"; // 发送人的id
  final String columnContent = "content"; // 内容
  final String columnType = "type"; // 消息内容格式
  final String columnAddTime = "addTime"; // 添加时间
  // final String columnReadingTime = "readingTime"; // 接收到的时间

  /// 创建表的sql语句
  @override
  createTableString() {
    return """
      create table $dbTableName (
        $columnId integer primary key,
        $columnLogId integer not null,
        $columnSendUid integer not null,
        $columnContent text not null,
        $columnType integer not null,
        $columnAddTime integer not null)
    """;
  }

  /// 表名
  @override
  tableName() {
    return dbTableName;
  }

  Future deleteTable() async {
    Database db = await getDataBase();
    await db.execute("""
        DROP TABLE $dbTableName;
      """);
  }

  // 获取所有的数据
  Future<List<Map<String, dynamic>>> all() async {
    Database db = await getDataBase();
    var results = await db.rawQuery("""
        SELECT * FROM $dbTableName
      """);
    return results;
  }

  // 分页
  Future<List<Map<String, dynamic>>> paginate(int page,
      {int limit = 10}) async {
    List<Map<String, dynamic>> lists = await all();
    if (lists.isEmpty == false) {
      int len = lists.length;
      Database db = await getDataBase();
      int hasPageNum = len ~/ limit + 1;
      if (page <= hasPageNum) {
        int offsetStart = (page - 1) * 10;
        var result = await db.rawQuery("""
          SELECT * FROM $dbTableName LIMIT $limit OFFSET $offsetStart;
          """);
        return result;
      }
      return [];
    }
    return [];
  }

  // 根据两个人的id查找出对应的聊天记录，并进行分页
  Future<List<Map<String, dynamic>>> queryPage(int uid, int otherId, int page,
      {int limit = 50}) async {
    Database db = await getDataBase();
    String where = """
        $columnSendUid = $uid OR $columnSendUid = $otherId ORDER BY $columnId DESC
    """;
    List<Map<String, dynamic>> lists =
        await db.query(dbTableName, where: where);
    int len = lists.length; // 总数
    int hasPageNum = len ~/ limit + 1;
    if (page <= hasPageNum) {
      int offsetStart = (page - 1) * 10;
      List<Map<String, dynamic>> result = await db.query(dbTableName,
          where: where, limit: limit, offset: offsetStart);
      return result;
    }
    return [];
  }

  // // 排序
  // Future order({String column = "id", DbOrder order = DbOrder.asc})async{
  //   Database db = await getDataBase();
  //   db.query(table)
  // }

  // 插入数据(需要先判断再插入)
  Future insertHasJudgment(SKModel.Lists itemData) async {
    Database db = await getDataBase();
    // 先查询本地数据R库是否有logId，有的话则不写入，没有的话则新增加一条记录。
    var result = await db.rawQuery("""
        SELECT * FROM $dbTableName WHERE $columnLogId = ${itemData.id}
      """);
    if (result.isEmpty == true) {
      SocketDbModel socketDbModel = SocketDbModel.toJsonModel(itemData);
      // 新增加一条记录。
       int id = await insert(socketDbModel);
       return id;
    }
  }

  // 插入数据(自己发送的消息插入到表)
  Future<int> insert(SocketDbModel socketDbModel) async {
    Database db = await getDataBase();
    // 新增加一条记录。
    int id = await db.transaction(
      (txn) async {
        int id = await txn.rawInsert('''
            INSERT INTO $dbTableName(
              $columnLogId, $columnSendUid, $columnContent, $columnType, 
              $columnAddTime
              ) VALUES(
                ${socketDbModel.logId}, ${socketDbModel.sendUid}, "${socketDbModel.content}",
                ${socketDbModel.type}, ${socketDbModel.addTime}
              )
            ''');
        return id;
      },
    );
    return id;
  }
}

// 用于写入到数据库的聊天记录模型
class SocketDbModel {
  int logId; // 服务器数据对应的id
  int sendUid; // 发送人的id
  String content; // 内容
  int type; // 消息内容格式
  int addTime; // 添加时间

  SocketDbModel.toJsonModel(SKModel.Lists itemData) {
    this.logId = itemData.id;
    this.sendUid = itemData.sendUid;
    this.content = itemData.text;
    this.type = itemData.type;
    this.addTime = itemData.addTime;
  }

  // 自己发送的聊天记录写入到本地数据库，先转换成模型，再写入数据库
  SocketDbModel.localSqlData(int sendUid, String content, ChatType type) {
    this.logId = -1;
    this.sendUid = sendUid;
    this.content = content;
    this.type = ChatTypeToInt.getData(type);
    this.addTime = DateTime.now().millisecondsSinceEpoch;
  }
}
